package net.hymnal.church;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Vector;

import android.app.Activity;
import android.util.Log;
 
public class HymnsManager {
	private static class LastSelectedHymn {
		public static int lastCommonHymn;
		public static int lastYoungHymn;
	}
	
	private static class TreeInt {
		public final int value;
		TreeInt(int val) {
			value = val;
		}
	}
	static final class ThemesTree {
		static String seletedMainTheme;
		static String seletedSubTheme;
		static ThemesTree instance = null;
		static String[] arrayMainThemes;
		static String[] arraySubThemesLast;
		static HashMap<String, Vector<TreeInt>> subMapLast;
		Vector<TreeInt> subNumbersLast;
		
		private ThemesTree() {
			themesTree = new HashMap<String, HashMap<String, Vector<TreeInt>>> ();			
		}
		HashMap<String, HashMap<String, Vector<TreeInt>>> themesTree;
		
		static ThemesTree getInstance() {
			if(instance == null) {
				instance = new ThemesTree();
			}
			return instance;
		}
		
		public void addHymn(SingleHymn h) throws IllegalArgumentException {
			if(h == null) {
				throw new IllegalArgumentException("h == null");
			}
			TreeInt tInt = new TreeInt(h.getNumber());
			String mainTheme = h.getMainTheme();
			String subTheme = h.getSubTheme();
			boolean mainThemeExist = false;
			mainThemeExist = themesTree.containsKey(mainTheme);
			if(mainThemeExist == false) {
				HashMap<String, Vector<TreeInt>> subItem = new HashMap<String, Vector<TreeInt>>();
				Vector<TreeInt> vector = new Vector<HymnsManager.TreeInt>();
				vector.add(tInt);
				subItem.put(subTheme, vector);
				themesTree.put(mainTheme, subItem);
			} else {
				boolean subThemeExist = false;
				HashMap<String, Vector<TreeInt>> subItem = themesTree.get(mainTheme);
				subThemeExist = subItem.containsKey(subTheme);
				if(subThemeExist == false) {
					HashMap<String, Vector<TreeInt>> newSubItem = new HashMap<String, Vector<TreeInt>>();
					Vector<TreeInt> vector = new Vector<HymnsManager.TreeInt>();
					vector.add(tInt);
					subItem.put(subTheme, vector);
					themesTree.put(mainTheme, subItem);
				} else {
					Vector<TreeInt> vector = subItem.get(subTheme);
					vector.add(tInt);
				}
			}
		}
		
		public String[] getMainThemesArray() {
			if(arrayMainThemes != null) {
				return arrayMainThemes;
			}
			Set set = themesTree.keySet();
			int size = set.size();
			arrayMainThemes = new String[size];
			Iterator i = set.iterator();
			int count = 0;
			while(i.hasNext()) {
				arrayMainThemes[count] = (String)i.next();
				count ++;
			}			
			return arrayMainThemes;
		}		
		
		public void seletSubThemesArray(int numMainTheme) {
			seletedMainTheme = arrayMainThemes[numMainTheme];
			subMapLast = themesTree.get(seletedMainTheme);
			Set<String> set = subMapLast.keySet();
			int size = set.size();
			arraySubThemesLast = new String[size];
			Iterator<String> i = set.iterator();
			int count = 0;
			while(i.hasNext()) {
				arraySubThemesLast[count] = (String)i.next();
				count ++;
			}
		}
		public static final String LINE_TOP_NAME = "TOP_LINE";
		public static final String LINE_BOTTOM_NAME = "BOTTOM_LINE";
		public List<Map<String, ?>> createSubItemList() {
			String subArray[] = getLastSelectedSubThemesArray();
			List<Map<String, ?>> items = new ArrayList<Map<String, ?>>();
			for(int i = 0; i < subArray.length; i++) {
				Map<String, Object> mapItem = new HashMap<String, Object>();
				mapItem.put(LINE_TOP_NAME, subArray[i]);
				String secondLine = getNumberAsStringArrayWith(seletedMainTheme, subArray[i]);
				mapItem.put(LINE_BOTTOM_NAME, secondLine);
				items.add(mapItem);
			}
			return items;
		}
		
		private int[] getNumberArrayWith(String mainTheme, String subTheme) {
			int result[] = null;
            HashMap<String, Vector<TreeInt>> subItem = 
            		themesTree.get(mainTheme);
            Vector<TreeInt> vectorTreeInt = subItem.get(subTheme);
            int size = vectorTreeInt.size();
            result = new int[size];
            for(int i = 0; i < size; i++) {            	 
            	result[i] = vectorTreeInt.elementAt(i).value;
            }
            return result;            
		}
		
		public String getNumberAsStringArrayWith(String mainTheme, String subTheme) {
			int result[] = getNumberArrayWith(mainTheme, subTheme);
			String strResult = "";			
			for(int i = 0; i < result.length; i++) {
				SingleHymn hymnItem = getSingleHymn(result[i] - 1);
				strResult += Integer.toString(result[i]);				 
				strResult += " : " + hymnItem.getFirstLine();
				if(i == (result.length - 1)){
					return strResult;
				}				
				strResult += "\n";
			}
			return strResult;			
		}
		
		public String[] getLastSelectedSubThemesArray () {
			return arraySubThemesLast;
		}
		
		public void selectVectorHymnsNumbers(int num) {
			seletedSubTheme = arraySubThemesLast[num];
			subNumbersLast = subMapLast.get(seletedSubTheme);			
		}
		public int[] getLastSelectedVector() {
			int size = subNumbersLast.size();
			int array[] = new int[size];
			for(int i = 0; i < size; i++) {
				TreeInt tInt = subNumbersLast.elementAt(i);
				array[i] = tInt.value;
			}
			return array;
		}
	}
	
	public enum HYMNS_TYPE {
		TYPE_NONE, TYPE_COMMON, TYPE_YOUNG
	};

	private static HYMNS_TYPE selectedType;
	static ArrayList<SingleHymn> m_arrayCommonHymns;
	static ArrayList<SingleHymn> m_arrayYoungHymns;

	
	
	static private int selectedCount;
	
	static public boolean isSelected() {
        return (selectedCount > 0);
	}
	
	static public void resetSelection() {
        selectedCount = 0;
	}
	
	
	static void selectHymnType(HYMNS_TYPE type){
		selectedType = type;
	}
	
	

	static void readYoungHymns(Activity a) {
		HymnsManager.m_arrayYoungHymns = new ArrayList<SingleHymn>();
		String fileName = Settings.PathesClass.youngHymnalPath;
		for (int i = 0; i < Settings.MAX_YOUNG_HYMNS; i++) {
			String appendStr = "";

			if (i < 100) {
				appendStr += "0";
			}

			if (i < 10) {
				appendStr += "0";
			}

			String fullName = fileName + appendStr + Integer.toString(i)
					+ ".txt";
			try {
				final InputStream is = a.getResources().getAssets()
						.open(fullName);
				if (is != null) {
					byte b_buffer[] = null;
					int fileSize = is.available();
					b_buffer = new byte[fileSize + 1];
					is.read(b_buffer);
					String text = new String(b_buffer, "Cp1251");
					SingleHymn singleHymn = new SingleHymn(i, text);
					HymnsManager.m_arrayYoungHymns.add(singleHymn);
				}
			} catch (IOException e) {
				Log.e("IO", "Young:File not found:" + i);
			}
		}
	}
	

	static void readCommonHymns(Activity a) {
		HymnsManager.m_arrayCommonHymns = new ArrayList<SingleHymn>();
		String FileName = Settings.PathesClass.commonHymnalPath + "r";
		for (int i = 0; i < Settings.MAX_COMMON_HYMNS; i++) {
			String fullName = FileName + Integer.toString(i) + ".txt";
			try {
				final InputStream is = a.getResources().getAssets()
						.open(fullName);
				if (is != null) {
					byte b_buffer[] = null;
					int fileSize = is.available();
					b_buffer = new byte[fileSize + 1];
					is.read(b_buffer);
					String text = new String(b_buffer, "Cp1251");
					SingleHymn singleHymn = new SingleHymn(i, text);
					HymnsManager.m_arrayCommonHymns.add(singleHymn);
				}
			} catch (IOException e) {
				System.out.println("read common hymns ex:" + e.getMessage());
			}
		}
	}
	

	static void readCommonMelodyTable(Activity a) {
		String fileName = Settings.PathesClass.tableCommonPath + Settings.PathesClass.tableMelodyFileName;
		HymnsManager.selectHymnType(HYMNS_TYPE.TYPE_COMMON);
		try {
			HymnsManager.ThemesTree inst = HymnsManager.ThemesTree.getInstance();
			final InputStream is = a.getResources().getAssets().open(fileName);
			final InputStreamReader isr = new InputStreamReader(is);
			final BufferedReader br = new BufferedReader(isr);
			String line = null;
			while((line = br.readLine())!=null) {
				//line = br.readLine();
				String[] strSplit = line.split("==");
				SingleHymn h = null;
				int englishNum = 0;
				for (int i = 0; i < strSplit.length; i++) {					
					if (i == 0) {
						int hNum = Integer.parseInt(strSplit[0]);
						h = HymnsManager.getSingleHymn(hNum - 1);
					}
					if (i == 1) {
						englishNum = Integer.parseInt(strSplit[i]);
						h.setEnglishNumber(englishNum);
					}
					if(h == null || strSplit[i] == "null") {
						continue;
					}
					if (i == 2) {
						// first line
						h.setFirstLine(strSplit[i]);
						continue;
					}
					if (i == 3) {
						// filename
						if(englishNum > 0) { 
						    h.setMelodyFileName(strSplit[i]);
						}
						continue;
					}
					if (i == 4) {
						if(englishNum > 0) {
						    h.setTuneMelodyFileName(strSplit[i]);
						}
						continue;
					}
					if (i == 5) {
						h.setMainTheme(strSplit[i]);
						continue;
					}
					if (i == 6) {
						h.setSubTheme(strSplit[i]);
						continue;
					}					
				}
				inst.addHymn(h);				
			}
			
		} catch (IOException e) { 
			System.out.println("No table for common_melydy hymns.");
		} finally {
			HymnsManager.selectHymnType(HYMNS_TYPE.TYPE_NONE);
		}
	}

	static int getNumberHymns() {
		if (selectedType == HYMNS_TYPE.TYPE_COMMON) {
			return HymnsManager.m_arrayCommonHymns.size();
		}
		if (selectedType == HymnsManager.HYMNS_TYPE.TYPE_YOUNG) {
			return HymnsManager.m_arrayYoungHymns.size();
		}
		return 0;
	}

	static SingleHymn getSingleHymn(int index) {
		if (HymnsManager.selectedType == HYMNS_TYPE.TYPE_COMMON) {
			return m_arrayCommonHymns.get(index);
		}
		if (HymnsManager.selectedType == HYMNS_TYPE.TYPE_YOUNG) {
			return m_arrayYoungHymns.get(index);
		}
		return null;
	}

	static boolean SelectHymns(String subString) {		
		selectedCount = 0;			
		int num = getNumberHymns();
		for (int i = 0; i < num; i++) {
			if (selectedType == HYMNS_TYPE.TYPE_COMMON) {
				SingleHymn h = m_arrayCommonHymns.get(i);
				h.checkTextAndSelect(subString);
				if (h.isSelected()) {
					selectedCount++;
				}
				continue;
			}
			if (selectedType == HYMNS_TYPE.TYPE_YOUNG) {
				SingleHymn h = m_arrayYoungHymns.get(i);
				h.checkTextAndSelect(subString);
				if (h.isSelected()) {
					selectedCount++;
				}
			}
			if (selectedType == HYMNS_TYPE.TYPE_NONE) {
				return false;
			}			
		}
		return (selectedCount > 0);		
	}
	
	static String[] getSelectedArray() {
		int k = 0;
		String[] array = new String[selectedCount];
		int num = getNumberHymns();
		for (int i = 0; i < num; i++) {
			SingleHymn h = getSingleHymn(i);
			if (h.isSelected()) {
				array[k] = Integer.toString(i + 1);
				String fLine = h.getFirstLine();
				if (fLine != null) {
					array[k] += " :" + fLine;
				}
				k++;
			}
		}		
		return array;
	}
	
	public static HYMNS_TYPE getSelectedType () {
		return selectedType;
	}
	
	public static int getLastSelectedHymn(HYMNS_TYPE type) {
		if(type == HYMNS_TYPE.TYPE_COMMON) {
			return LastSelectedHymn.lastCommonHymn;
		}
		if(type == HYMNS_TYPE.TYPE_YOUNG) {
			return LastSelectedHymn.lastYoungHymn;
		}
		return 1;
	}
	
	public static void setLastSelectedHymn(HYMNS_TYPE type, int last) {
		if(type == HYMNS_TYPE.TYPE_COMMON) {
			LastSelectedHymn.lastCommonHymn = last;
		}
		if(type == HYMNS_TYPE.TYPE_YOUNG) {
			LastSelectedHymn.lastYoungHymn = last;
		}		
	}
}
